﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.InteropServices;
using huqiang.Data;
namespace CustomReflection
{
    class Program
    {

        public class Wepon
        {
            public string Name;
        }

        public class People
        {
            public int Age;
            public int Tow { get; set; }

            public byte Sex;

            public string Name;

            public long Time;

            public Wepon wepon;
        }

        //IntPtr ConventToIntPtr (object pVoid)
        //{
        //   var handle = GCHandle.Alloc(pVoid);  //记得要释放  handle.Free();
        //    IntPtr mpVoid = GCHandle.ToIntPtr(handle);
        //}

        //void freeObject()
        //{
        //    handle.Free();
        //}

        //object ConventToobject(IntPtr pVoid)
        //{
        //    Object obj = GCHandle.FromIntPtr(pVoid).Target;
        //    UserTest temp = obj as UserTest;
        //}

        public static Type DynamicCreateType()
        {
            //动态创建程序集
            AssemblyName DemoName = new AssemblyName("DDDDD");
            AssemblyBuilder dynamicAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(DemoName, AssemblyBuilderAccess.RunAndSave);
            //动态创建模块
            ModuleBuilder mb = dynamicAssembly.DefineDynamicModule(DemoName.Name, DemoName.Name + ".dll");
            //动态创建类MyClass

            TypeBuilder tb = mb.DefineType("GeneralTool", TypeAttributes.Public);

            //动态创建字段
            FieldBuilder fb = tb.DefineField("myField", typeof(System.String), FieldAttributes.Private);
            //动态创建构造函数
            Type[] clorType = new Type[] { typeof(System.String) };
            ConstructorBuilder cb1 = tb.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, clorType);
            //生成指令
            ILGenerator ilg = cb1.GetILGenerator();//生成 Microsoft 中间语言 (MSIL) 指令
            ilg.Emit(OpCodes.Ldarg_0);
            ilg.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes));
            ilg.Emit(OpCodes.Ldarg_0);
            ilg.Emit(OpCodes.Ldarg_1);
            ilg.Emit(OpCodes.Stfld, fb);
            ilg.Emit(OpCodes.Ret);

            //动态创建属性
            PropertyBuilder pb = tb.DefineProperty("GeneralTool", PropertyAttributes.HasDefault, typeof(string), null);

            MethodBuilder mainMethodBuilder2 = tb.DefineMethod("SetObject", MethodAttributes.Static | MethodAttributes.Public, CallingConventions.Standard,
                 null, new Type[] { typeof(void*), typeof(object) }
                );

            ILGenerator ilGenerator = mainMethodBuilder2.GetILGenerator();
            ilGenerator.Emit(OpCodes.Ldarg_0);
            ilGenerator.Emit(OpCodes.Ldarg_1);
            ilGenerator.Emit(OpCodes.Stobj, typeof(object));
            ilGenerator.Emit(OpCodes.Ret);



            MethodBuilder mainMethodBuilder3 = tb.DefineMethod("VoidToObject", MethodAttributes.Static | MethodAttributes.Public, CallingConventions.Standard,
                  typeof(object), new Type[] { typeof(void*) }
                );

            ILGenerator ilGenerator3 = mainMethodBuilder3.GetILGenerator();
            ilGenerator3.Emit(OpCodes.Ldarg_0);
            //ilGenerator3.Emit(OpCodes.Ldobj, typeof(object));
            ilGenerator3.Emit(OpCodes.Ret);



            MethodBuilder mainMethodBuilder4 = tb.DefineMethod("ObjectToVoid", MethodAttributes.Static | MethodAttributes.Public, CallingConventions.Standard,
                  typeof(void*), new Type[] { typeof(object) }
                );

            ILGenerator ilGenerator4 = mainMethodBuilder4.GetILGenerator();
            //ilGenerator4.Emit(OpCodes.Ldarga_S, 0);
            //ilGenerator4.Emit(OpCodes.Conv_U);
            //ilGenerator4.Emit(OpCodes.Ldind_I);
            //ilGenerator4.Emit(OpCodes.Ret);

            ilGenerator4.Emit(OpCodes.Ldarg_0);
            ilGenerator4.Emit(OpCodes.Ret);


            //使用动态类创建类型
            Type classType = tb.CreateType();
            //保存动态创建的程序集 (程序集将保存在程序目录下调试时就在Debug下)
            dynamicAssembly.Save(DemoName.Name + ".dll");
            //创建类
            return classType;
        }

        public class GG
        {
            public long Name;
            public long Name2;
            public long Name3;
            public long Name4;
            public long Name5;
        }

        public unsafe static void* ObjectToVoid(long P_0)
        {
            return *(void**)&P_0;
        }

        unsafe static void Main(string[] args)
        {
            Type type32 = DynamicCreateType();


            var gg = new GG();
            gg.Name = 1;
            gg.Name2 = 2;
            gg.Name3 = 3;
            gg.Name4 = 4;
            gg.Name5 = 5;
            TypedReference tfdd = __makeref(gg);

            var handle22 = GCHandle.Alloc(gg);  //记得要释放  handle.Free();
            IntPtr mpVoid = GCHandle.ToIntPtr(handle22);

            long* cccc = (long*)mpVoid;
            List<long> list3 = new List<long>();
            for (int i = 0; i < 10; i++)
            {
                list3.Add(cccc[i]);
            }

            Object obj = GCHandle.FromIntPtr(mpVoid).Target;
            GG temp = obj as GG;
            void* ccvoid2 = UnsafeOperation.ObjectToVoid(obj);


            long* cc = (long*)UnsafeOperation.GetObjectAddr(tfdd);
            void* ccvoid = UnsafeOperation.ObjectToVoid(gg);
            object vvvv = UnsafeOperation.VoidToObject(ccvoid);
            int sizes = UnsafeOperation.SizeOf(typeof(GG));

            void* ccvoidP = &ccvoid;
            //object ojbk = type32.GetMethod("SetObject").Invoke(null, new object[] { ccvoid });
            //GeneralTool generalTool = new GeneralTool("c");
            //object vvvv2 = GeneralTool.GetObject(ccvoid);
            //Console.WriteLine(vvvv2);

            //void* vvvv2 = GeneralTool.ObjectToVoid(gg);

            //void* ccvoid23 = (void*)vvvv2;


            List<long> list = new List<long>();
            for (int i = 0; i < 10; i++)
            {
                list.Add(cc[i]);
            }

            int size = *((int*)typeof(GG).TypeHandle.Value + 1);

            long dfff = (long)typeof(GG).TypeHandle.Value;

            long dfff2 = *(long*)typeof(GG).TypeHandle.Value;
            var cc2 = (int*)dfff;
            List<int> list2 = new List<int>();
            for (int i = 0; i < 7; i++)
            {
                list2.Add(cc2[i]);
            }

            Type typ = typeof(People);

            var nf = typ.GetField("Age");

            var handle = nf.FieldHandle;

            int os1 = UnsafeOperation.GetFeildOffset(handle.Value);

            nf = typ.GetField("Sex");

            var handle2 = nf.FieldHandle;

            int os2 = UnsafeOperation.GetFeildOffset(handle2.Value);

            nf = typ.GetField("wepon");

            var handle3 = nf.FieldHandle;

            int os3 = UnsafeOperation.GetFeildOffset(handle3.Value);

            nf = typ.GetField("Name");

            var handle4 = nf.FieldHandle;

            int os4 = UnsafeOperation.GetFeildOffset(handle4.Value);

            People people = new People();

            people.Age = 16;

            people.Name = "Hello";

            people.Tow = 6;

            people.Sex = 4;

            people.Time = -1;

            Wepon wepon = new Wepon();

            wepon.Name = "机枪";

            TypedReference tf = __makeref(people);

            IntPtr c = UnsafeOperation.GetObjectAddr(tf);

            *(int*)(c + os1) = 200;//设置年龄

            *(byte*)(c + os2) = 3;//设置性别

            UnsafeOperation.SetObject(c + os3, wepon);//设置武器类

            UnsafeOperation.SetObject(c + os4, "打的不错哦!呵呵.");//设置名字

            Console.WriteLine(people.Age);

            Console.WriteLine(people.Sex);

            Console.WriteLine(people.wepon.Name);

            Console.WriteLine(people.Name);

            Console.ReadKey(false);

        }

    }

}
